#pragma once

#include<iostream>
#include <assert.h>
using namespace std;

// 一个到底可以重载哪些运算符？->哪些运算符对这个类型有意义
class Date
{
	// 友元函数 -- 这个函数内部可以使用Date对象访问私有保护成员
	friend ostream& operator<<(ostream& out, const Date& d);
	friend istream& operator>>(istream& in, Date& d);
public:
	// 会频繁调用，所以直接放在类里面定义作为inline
	int GetMonthDay(int year, int month)// 获取某年某月的天数
	{
		//这里的数组会频繁使用，所以加上static
		static int days[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
		int day = days[month];
		if (month == 2
			&& ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)))//先判断是否是2月
		{
			day += 1;
		}
		return day;
	}
	// 会频繁调用，所以直接放在类里面定义作为inline
	bool CheckDate()
	{
		if (_year >= 1
			&& _month > 0 && _month < 13
			&& _day > 0 && _day <= GetMonthDay(_year, _month))
		{
			return true;
		}
		else
		{
			return false;
		}
	}

	// 构造会频繁调用，所以直接放在类里面定义作为inline
	Date(int year = 1, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;

		/*if (!CheckDate())
		{
			Print();
			cout << "刚构造的日期非法" << endl;
		}*/

		assert(CheckDate());
	}

	void Print() const;

	bool operator==(const Date& d) const;
	bool operator>(const Date& d) const;
	bool operator!=(const Date& d) const;
	bool operator>=(const Date& d) const;
	bool operator<(const Date& d) const;
	bool operator<=(const Date& d) const;

	Date operator+(int day) const;
	Date& operator+=(int day);

	// 特殊处理，使用重载区分，后置++重载增加一个int参数跟前置构成函数重载进行区分
	Date& operator++(); // 前置
	Date operator++(int); // 后置

	// d1 - 100
	Date operator-(int day) const;
	Date& operator-=(int day);

	Date& operator--(); // 前置
	Date operator--(int); // 后置

	// d1 - d2
	int operator-(const Date& d) const;

	//void operator<<(ostream& out);
private:
	int _year;
	int _month;
	int _day;
};

// 流插入重载
inline ostream& operator<<(ostream& out, const Date& d)
{
	out << d._year << "年" << d._month << "月" << d._day << "日" << endl;
	return out;
}

// 流提取重载
inline istream& operator>>(istream& in, Date& d)
{
	in >> d._year >> d._month >> d._day;
	assert(d.CheckDate());

	return in;
}

//#pragma once
//#include <iostream>
//using namespace std;
//
//class Date 
//{
//public:
//	Date(int year = 1, int month = 1, int day = 1);    // 全缺省构造
//	int GetMonthDay(int year, int month) const;       // 获取某年某月对应的天数
//	void Print() const;                                // 打印函数
//
//	bool operator>(const Date& d) const;               // d1 > d2
//	bool operator==(const Date& d) const;              // d1 == d2 
//	bool operator>=(const Date& d) const;          // d1 >= d2
//	bool operator<(const Date& d) const;           // d1 < d2
//	bool operator<=(const Date& d) const;          // d1 <= d2
//	bool operator!=(const Date& d) const;          // d1 != d2
//
//	Date& operator+=(int day);				           // d1 += 100
//	Date& operator-=(int day);				           // d1 -= 100
//	Date operator+(int day) const;                 // d1 + 100
//	Date operator-(int day) const;			       // d1 - 100
//
//	Date& operator++();				                   // ++d1;
//	Date operator++(int);				               // d1++;
//	Date& operator--();                                // --d1;
//	Date operator--(int);                              // d1--;
//
//	int operator-(const Date& d) const;                // 日期减日期
//	void PrintWeekDay() const;                         // 返回星期几
//
//private:
//	int _year;
//	int _month;
//	int _day;
//};